package interaction.sampling;

import java.util.Arrays;

public class Samples {
	public static Sample deviation(Sample standard, Sample comparison)
	{
		int maxSize = getMaximumSize(standard, comparison);
		Sample deviations = new Sample(maxSize);
		for (int i = 0; i < maxSize; i++) {
			deviations.add(comparison.get(i) - standard.get(i));
		}
		return deviations;
	}
	
	public static Sample average(Sample[] samples)
	{
		int maxSize = getMaximumSize(samples);
		Sample result = new Sample(maxSize);
		for (int i = 0; i < maxSize; i++) {
			double total = 0;
			for (int j = 0; j < samples.length; j++) {
				if (samples[j].size() > i) {
					total += samples[j].get(i);
				}
			}
			result.add((float) (total / samples.length));
		}
		return result;
	}
	
	public static Sample select(Sample[] samples, int index)
	{
		Sample result = new Sample(samples.length);
		for (int i = 0; i < samples.length; i++) {
			result.add(samples[i].get(index));
		}
		return result;
	}
	
	public static Sample getLeftDeltaValues(Sample s)
	{
		if (s.size() < 1) {
			return new Sample(0);
		}
		
		Sample deltas = new Sample(s.size() - 1);
		float previousValue = s.get(0);
		for (int i = 1; i < s.size(); i++) {
			deltas.add(previousValue - s.get(i));
			previousValue = s.get(i);
		}
		return deltas;
	}
	
	public static Sample getLeftAndRightDeltaValues(Sample s)
	{
		if (s.size() < 3) {
			return new Sample(0);
		}
		
		Sample deltas = new Sample(s.size() - 2);
		float previousValue = s.get(0);
		float nextValue = s.get(2);
		for (int i = 1; i < s.size() - 2; i++) {
			deltas.add(nextValue - previousValue);
			previousValue = s.get(i);
			nextValue = s.get(i+2);
		}
		return deltas;
	}
	
	public static int getMaximumSize(Sample ... samples)
	{
		int[] sizes = new int[samples.length];
		for (int i = 0; i < samples.length; i++) {
			sizes[i] = samples[i].size();
		}
		Arrays.sort(sizes);
		return sizes[sizes.length - 1];
	}
	
	public static int[] getSizes(Sample[] samples)
	{
		int[] sizes = new int[samples.length];
		
		for (int i = 0; i < samples.length; i++) {
			sizes[i] = samples[i].size();
		}
		
		return sizes;
	}
	
	public static double getAverageSize(Sample[] samples)
	{
		return getTotalSize(samples) / samples.length;
	}
	
	public static double getTotalSize(Sample[] samples)
	{
		int totalSize = 0;
		
		for (Sample s : samples) {
			totalSize += s.size();
		}
		
		return totalSize;
	}
	
	public static double getSizeStandardDeviation(Sample[] samples)
	{
		double average = getAverageSize(samples);
		int[] sizes = getSizes(samples);
		
		double deviation = 0;
		for (int size : sizes) {
			deviation += Math.pow(size - average, 2);
		}
		return Math.sqrt(deviation / sizes.length);
	}
}
